﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcRags.Pagination
{
    public static class PaginationExtentions
    {
        public static IOrderedQueryable<T> Paginate<T>(this Controller controller, IOrderedQueryable<T> entries)
        {
            int entriesPerPage = GetEntriesPerPage(controller);
            controller.ViewData[PaginationSettings.ViewDataKeyPageEntries] = entriesPerPage;
            int totalEntriesCount = entries.Count();
            controller.ViewData[PaginationSettings.ViewDataKeyTotalEntriesCount] = totalEntriesCount;

            if (!entries.Any())
            {
                controller.ViewData[PaginationSettings.ViewDataKeyPage] = 0;
                controller.ViewData[PaginationSettings.ViewDataKeyPageCount] = 0;
                return entries;
            }

            int page = GetPage(controller);

            int limit = entriesPerPage;
            int pageCount = (totalEntriesCount + limit - 1) / limit;

            if (page < 1)
                page = 1;
            else if (page > pageCount)
                page = pageCount;

            int offset = (page - 1) * limit;

            controller.ViewData[PaginationSettings.ViewDataKeyPage] = page;
            controller.ViewData[PaginationSettings.ViewDataKeyPageCount] = pageCount;
            
            return (IOrderedQueryable<T>)entries.Skip(offset).Take(limit);
        }

        private static int GetPage(Controller controller)
        {
            int page;
            if (!Int32.TryParse(controller.Request.Params[PaginationSettings.RequestKeyPage], out page))
                page = 1;
            return page;
        }

        private static int GetEntriesPerPage(Controller controller)
        {
            int tmpEntriesPerPage;
            if (controller.Request.Params[PaginationSettings.RequestKeyEntriesPerPage] != null)
            {
                if (!Int32.TryParse(controller.Request.Params[PaginationSettings.RequestKeyEntriesPerPage], out tmpEntriesPerPage))
                    tmpEntriesPerPage = PaginationSettings.DefaultEntriesPerPage;
            }
            else if (controller.Session[PaginationSettings.SessionKeyEntriesPerPage] is int)
            {
                tmpEntriesPerPage = (int)controller.Session[PaginationSettings.SessionKeyEntriesPerPage];
            }
            else
            {
                tmpEntriesPerPage = PaginationSettings.DefaultEntriesPerPage;
            }
            controller.Session[PaginationSettings.SessionKeyEntriesPerPage] = tmpEntriesPerPage;
            return tmpEntriesPerPage;
        }
    }
}